(** Bombs-Must-Detonate: IR Compiler Signature 
    @author: Brian Go*)

type instruction =
(** 0-arity *)
    Push
  | Pop
  | Read
  | Print
  | PrintLn
  | Swap
  | Stop
  | Return
  | Cons
  | Car
  | Cdr
  | IsNull
  | Nil
  | GetElem
  | SetElem
  | And
  | Or
  | Add
  | Sub
  | Mul
  | Div
  | DivI
  | RemI
  | Concat
  | Neg
  | Frac
  | Int
  | Lt
  | Gt
  | Lte
  | Gte
  | Eq
  | Neq
  | ConstUninit
  | Apply
(** 1-arity *)
  | ConstInt of int
  | ConstFloat of float
  | ConstString of string
  | PushSf of string
  | Assign of int
  | Acc of int
  | Rev of int
  | MakeBlock of int
  | MakeBlockFilled of int
  | AllocFields of int
  | GetField of int
  | SetField of int
  | Call of string
  | Jmp of string
  | Jz of string
  | Jnz of string
  | RPC of string
  | Label of string
  | Comment of string
  | Annotation of string
  | GetElemStatic of int
  | SetElemStatic of int
(** 2-arity *)
  | MakeBlockStatic of int * int

type ir_instruction =
    Instruction of instruction
(** Ir-Specific *)
  | GetVar of string
  | SetVar of string
  | NoteVar of string * int
  | NoteFunction of string
  | If of ir_buffer * ir_buffer * ir_buffer (** test, then, else *)
  | For of ir_buffer * ir_buffer * ir_buffer * ir_buffer  (** init, test, step, body *)
  | While of ir_buffer * ir_buffer (** test, body *)
  | DoWhile of ir_buffer * ir_buffer (** body, test *)
  | Break
  | Continue
  | BeginScope
  | EndScope
  | EndScopeSf
  | EndScopeSfRPC
  | DeclareGlobal of string

and ir_buffer = ir_instruction list

(** Compiles the AST to a list of IR instructions *)
val compile_ir : Ast.src_program -> ir_buffer

(** Gets the string representation of a given IR instruction *)
val string_of_instruction: instruction -> string

(** Writes the IR buffer to the given output channel *)
val print_ir_buffer : out_channel -> ir_buffer -> unit

(** Makes a label from the given string which has a unique prefix *)
val make_label : string -> string
